package cqut.wys.createclass;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;

import java.lang.reflect.Method;

/**
 * --------神兽出没--------/
 *   ┌─┐     ┌─┐
 * ┌─┘─┴─────┘─┴─┐
 * │      ─      │
 * │  ┬─┘   └─┬  │
 * │             │
 * │      ┴      │  Code is far away from bug with the animal protecting
 * └───┐      ┌──┘  神兽保佑,代码无bug
 *     │      │
 *     │      └──────┐
 *     │             ├┐
 *     │             ┌┘
 *     └┐ ┐ ┌───┬─┐ ┌┘
 *      │ ┤ ┤   │ ┤ ┤
 *      └─┴─┘   └─┴─┘
 * --------感觉萌萌哒--------/
 *
 * 创建类例子
 * @author wuyoushan
 * @date 2018/5/18
 */
public class CreateExample {

    public static void main(String[] args) throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        CtClass cc = classPool.makeClass("cqut.wys.createclass.User");

        //创建属性
        CtField field0 = CtField.make("private int id;",cc);
        CtField field1 = CtField.make("private String name;",cc);
        cc.addField(field0);
        cc.addField(field1);

        //创建方法
        CtMethod method1 = CtMethod.make("public String getName(){return name;}",cc);
        CtMethod method2 = CtMethod.make("public void setName(String name){this.name = name;}",cc);
        cc.addMethod(method1);
        cc.addMethod(method2);

        //添加构造方法
        CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType,
                classPool.get("java.lang.String")},cc);
        constructor.setBody("{this.id=id;this.name=name;}");
        cc.addConstructor(constructor);

        //无参构造方法
        CtConstructor cons = new CtConstructor(null,cc);
        cons.setBody("{}");
        cc.addConstructor(cons);

//        cc.writeFile("E:/workspace/TestCompiler/src");

        Class c = cc.toClass();
        Object obj = c.newInstance();
        Method method = c.getMethod("setName",String.class);
        method.invoke(obj,"hello");

        Method m = c.getMethod("getName",null);
        Object result = m.invoke(obj,null);
        System.out.println(result);
    }
}
